#include "views/hierarchicalbundleview.h"
#include "ui_hierarchicalbundleview.h"

HierarchicalBundleView::HierarchicalBundleView(QWidget *parent) :
    AbstractView(parent),
    ui(new Ui::HierarchicalBundleView)
{
    ui->setupUi(this);

    aTemplate = NULL;

    renderer = vtkRenderer::New();
    ui->qvtkWidget->GetRenderWindow()->AddRenderer(renderer);

	qVTKslot = vtkEventQtSlotConnect::New();

    ui->hierarchicalSlider->setRange(0.0,1.0,0.01);
	ui->hierarchicalSlider->setValue(0.8);
	
	connect(ui->hierarchicalSlider,SIGNAL(sliderMoved(double)),this,SLOT(bundleStrengthChanged(double)));

}

HierarchicalBundleView::~HierarchicalBundleView()
{
    delete ui;
}

void HierarchicalBundleView::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void HierarchicalBundleView::bundleStrengthChanged(double value)
{	
	if(view)
		view->SetBundlingStrength(value);

	this->renderer->GetRenderWindow()->Render();
}

void HierarchicalBundleView::graphSelectionChanged(vtkObject *caller, unsigned long eventId, void *callData,void *somethingElse)
{
	printf("");
}

void HierarchicalBundleView::setNetwork(FunctionalNetwork *n)
{
	AbstractView::setNetwork(n);

	updateGraph();
	
}

void HierarchicalBundleView::updateSelection(){
	
	
}

void HierarchicalBundleView::updateView()
{
	for(int i = 0;i<network->getLinks().size();i++)
	{
		double corr = network->getLinks().at(i)->correlation();
		corrArray->SetValue(i,corr);
	}

	vtkActorCollection* coll = view->GetRenderer()->GetActors();
	//last item contains the polydata lines
	coll->GetLastItem()->GetMapper()->SetLookupTable(ColorMap::getInstance()->getLookupTable());
	coll->GetLastItem()->GetMapper()->SetColorModeToMapScalars();
	coll->GetLastItem()->GetMapper()->SetScalarModeToUseCellFieldData();

	view->Update();
	view->GetRenderWindow()->Render();
	//vtkSelection *selection = vtkSelection::New();
	/*vtkSmartPointer<vtkSelection> selection = vtkSmartPointer<vtkSelection>::New();

	vtkSelectionNode *node = vtkSelectionNode::New();
	vtkIdTypeArray *idTypeArr = vtkIdTypeArray::New();

	for(int i = 0;i < network->getSelection().size();i++)
	{
		int idx = network->getLinks().indexOf(network->getSelection().at(i));
		idTypeArr->InsertNextValue(idx);
	}
	node->SetSelectionList(idTypeArr);

	view->GetRepresentation(0)->Select(view,selection);*/
}

void HierarchicalBundleView::updateGraph()
{
	reader1 = vtkXMLTreeReader::New();
#ifdef _DEBUG
	QString fPath(tr(DATA_ROOT)+tr("/tree.xml"));
#else
	QString fPath(QDir::currentPath()+"/Data/tree.xml");
#endif

	reader1->SetFileName(fPath.toStdString().c_str());
	reader1->SetEdgePedigreeIdArrayName("tree edge");
	reader1->GenerateVertexPedigreeIdsOff();
	reader1->SetVertexPedigreeIdArrayName("id");

	table = vtkTable::New();
	id1Array = vtkIntArray::New();
	id2Array = vtkIntArray::New();
	corrArray = vtkDoubleArray::New();
    id1Array->SetName("region1");
    id2Array->SetName("region2");
	corrArray->SetName("correlation");

	bool useAbs = false;

	for(int i = 0 ;i<network->getRegions().size();i++)
	{
		for(int j = i+1 ;j<network->getRegions().size();j++)
		{
			id1Array->InsertNextValue(network->getRegions().at(i)->info().RegionID);
			id2Array->InsertNextValue(network->getRegions().at(j)->info().RegionID);
			if(useAbs)
				corrArray->InsertNextValue(abs(network->getLink(i,j)->correlation()));
			else
				corrArray->InsertNextValue(network->getLink(i,j)->correlation());
		}
	}

	table->AddColumn(id1Array);
	table->AddColumn(id2Array);

	table2Graph = vtkTableToGraph::New();
	table2Graph->SetInput(table);
	table2Graph->SetDirected(false);
	table2Graph->AddLinkEdge("region1","region2");

	reader1->Update();
	table2Graph->Update();

	vtkGraph* graph = table2Graph->GetOutput();
	graph->GetEdgeData()->AddArray(corrArray);
	graph->GetFieldData()->AddArray(corrArray);

	view = vtkHierarchicalGraphView::New();
	view->SetHierarchyFromInputConnection(reader1->GetOutputPort());
	view->SetGraphFromInput(graph);

	view->SetEdgeColorArrayName("correlation");
	view->SetVertexColorArrayName("VertexDegree");
	view->SetColorVertices(true);
	view->SetColorEdges(true);
	view->SetVertexLabelArrayName("name");
	view->SetVertexLabelVisibility(true);
	view->SetScalingArrayName("TreeRadius");

	view->Update(); // Needed for now

	layout = vtkTreeLayoutStrategy::New();
	layout->SetAngle(360);
	layout->SetRadial(true);
	layout->SetLogSpacingValue(0.8);
	layout->SetLeafSpacing(0.9);
  
	view->SetLayoutStrategy(layout);

	qVTKslot->Connect(view->GetRepresentation(0),vtkCommand::SelectionChangedEvent,this,SLOT(on_selectionChanged(vtkObject*, unsigned long, void*, void*)));

    view->SetupRenderWindow(renderer->GetRenderWindow());
 	view->GetRenderWindow()->SetMultiSamples(0);

	//vtkViewTheme* const theme = vtkViewTheme::CreateMellowTheme();
	vtkViewTheme* myTheme = vtkViewTheme::New();
	myTheme->SetBackgroundColor(1,1,1);
	myTheme->SetBackgroundColor2(0.9,0.9,0.9);

	myTheme->SetCellAlphaRange(0.1,0.3);
	
	myTheme->SetLineWidth(1);
	view->ApplyViewTheme(myTheme);
	myTheme->Delete();
	
	vtkActorCollection* coll = view->GetRenderer()->GetActors();
	//last item contains the polydata lines
	coll->GetLastItem()->GetMapper()->SetLookupTable(ColorMap::getInstance()->getLookupTable());
	coll->GetLastItem()->GetMapper()->SetColorModeToMapScalars();
	coll->GetLastItem()->GetMapper()->SetScalarModeToUseCellFieldData();

	renderer->GetRenderWindow()->Render();

}

void HierarchicalBundleView::on_matrixChanged()
{
	AbstractView::on_matrixChanged();
}

void HierarchicalBundleView::on_selectionChanged(vtkObject* caller, unsigned long vtk_event, void* client_data, void* call_data)
{
	vtkSelection *sel = (vtkSelection *)call_data;
	int nrNodes = sel->GetNumberOfNodes();
	SelectedLinks newSelection;
	if(nrNodes==0)
	{
		setSelection(newSelection);
		return;
	}
	vtkSelectionNode *sn = sel->GetNode(0);
	int dataType = sn->GetSelectionList()->GetDataType();
	switch(dataType)
	{
	case VTK_STRING: //a node is selected. currently not implemented
		{			
			/*vtkStringArray* arr = (vtkStringArray*)sn->GetSelectionList();
			int nrt = arr->GetNumberOfTuples();
			for(int i = 0;i<nrt;i++)
			{
				std::string val = arr->GetValue(i);
			}*/
		}
		break;
	case VTK_ID_TYPE: //links are selected
		{
			vtkIdTypeArray* arr = (vtkIdTypeArray*)sn->GetSelectionList();
			int nrt = arr->GetNumberOfTuples();
			for(int i = 0;i<nrt;i++)
			{
				int val = arr->GetValue(i);
				newSelection.push_back(network->getLinks().at(val));
			}
			setSelection(newSelection);
		}
		break;
	}
}